from ast import Dict
from venv import create

from celery.app import task
from numpy import record
from pandas.io.formats.printing import EscapeChars
from sqlalchemy.sql.coercions import expect
import init
from init import db
from init import cc
from init import app
from init import cosmeticsChecker
from init import cosmeticsWithPicChecker
from init import commodityChecker
from init import secondMedicalChecker
from init import digitalChecker
from init import officesuppliesChecker
from init import clothesChecker
from user import userservice
from user.vip_service import vip_service
from task import checker_task
from celery import Celery
from task.cm_task import CmTask
from task.cm_task import CmRecord
import json
from concurrent.futures import ThreadPoolExecutor
import threading
import time
import os
from dotenv import load_dotenv
from typing import List, final
from sqlalchemy import create_engine, engine, text, update, table, column, values, select
from sqlalchemy.orm import scoped_session, sessionmaker

load_dotenv()



engine = create_engine(
    os.getenv('SQLALCHEMY_DATABASE_URI'),
    pool_size=10,
    max_overflow=20,
    pool_recycle=3600)
Session = scoped_session(sessionmaker(bind=engine))
executor = ThreadPoolExecutor(max_workers=2)

def create_tasks_from_products(filename:str, products, user_id, category:int) -> CmRecord:  

    createTime = int(time.time())
    record = CmRecord(
        create_time=int(time.time()),
        state=0,  # 排队中
        record_name=filename,
        category=1,
        user_id=user_id
    )
    db.session.add(record)
    db.session.flush()  # 获取record.id
    tasks = []
    for product in products:
        task = CmTask(
            create_time=createTime,
            state=0,  # 排队中
            task_param=json.dumps(product),
            task_result='',
            record_id=record.id,
            task_type=2
        )
        db.session.add(task)
        tasks.append(task)

    db.session.commit()
    # 提交所有任务到线程池

    executor.submit(create_queue_for_task, record.id, [task.id for task in tasks])
    return record

def create_queue_for_task(record_id, taskIds):
    # 创建线程池，限制最大并发数
    with Session() as s:
        try:
            record = s.query(CmRecord).filter(CmRecord.id == record_id).first()
            record.state = 1  # 处理中
            update_record_state(s,record)
            s.commit()  # 提交状态更新，释放锁
            finalRes = 0
            tasks = s.query(CmTask).filter(CmTask.id.in_(taskIds)).all()
            for task in tasks:
                res = True
                
                try:
                    res = process_task(s, task)
                    s.commit()
                    if res:
                        finalRes += 1
                except Exception as e:
                    print('process error' + str(e))
            
            if finalRes == 0:
                record.state = 4  # 失败
            elif finalRes == len(tasks):
                record.state = 2  # 完全成功
            else:
                record.state = 3  # 部分成功
            record.end_time = int(time.time())
            update_record_state_endTime(s,record)
            s.commit()  # 提交最终状态
        except Exception as e:
            print('create queue error' + str(e))

    
def update_record_state(s:Session, record:CmRecord):
    stmt = (
            update(CmRecord)
            .where(CmRecord.id == record.id)
            .values(state=record.state)
        )
    s.execute(stmt)

def update_record_state_endTime(s:Session, record:CmRecord):
    stmt = (
            update(CmRecord)
            .where(CmRecord.id == record.id)
            .values(state=record.state, end_time = record.end_time)
        )
    s.execute(stmt)

            
def process_task(s:Session, task:CmTask) -> bool:
    # 获取任务并处理
    try:
        
        task_param_dict = json.loads(task.task_param)
        prodcut_name = task_param_dict['product_name']
        product_pics = task_param_dict['product_pics']
        result = init.check_product_name(prodcut_name, product_pics)
        task.task_result = json.dumps(result)
        task.state=2
        return True
    except Exception as e:
        print('process error' + str(e))
        task.state = 3  # 失败
        task.task_result = 'error'
        return False
    finally:
        task.end_time = int(time.time())
        stmt = (
            update(CmTask)
            .where(CmTask.id == task.id)
            .values(end_time=task.end_time, state=task.state, task_result=task.task_result)
        )
        # 查询对象
        s.execute(stmt)

def process_sync_task(user_id:int, prodcut_name:str, product_pics:List[str]) -> str:
    # 获取任务并处理
    try:
        createTime = int(time.time())

        record = CmRecord(
            create_time= createTime,
            state=1,  # 排队中
            record_name=prodcut_name,
            category=2,
            user_id=user_id
        )
        db.session.add(record)
        db.session.flush()  # 获取record.id

        params = {"product_name":prodcut_name, "product_pics":product_pics}
        task = CmTask(
            create_time=createTime,
            state=0,  # 排队中
            task_param=json.dumps(params),
            task_result='',
            task_type=1,
            record_id=record.id
        )
        db.session.add(task)
        db.session.flush()  # 获取task.id
        
        # 扣除用户次数
        success, message = vip_service.consume_frequency(user_id, 1)
        if not success:
            raise Exception("-10010001")
        
        result = init.check_product_name(prodcut_name, product_pics)
        task.task_result = json.dumps(result)
        task.state=2
        record.state = 2
        return result
    except Exception as e:
        print('process error' + str(e))
        task.state = 3  # 失败
        task.task_result = 'error'
        record.state = 3
        if str(e) == "-10010001":
            return '-10010001'
        return 'error'
    finally:
        endTime = int(time.time())
        task.end_time = endTime
        stmt = (
            update(CmTask)
            .where(CmTask.id == task.id)
            .values(end_time=endTime, state=task.state, task_result=task.task_result)
        )
        # 查询对象
        db.session.execute(stmt)
        stmt = (
            update(CmRecord)
            .where(CmRecord.id == record.id)
            .values(state=record.state, end_time = endTime)
        )
        db.session.execute(stmt)
        db.session.commit()

def get_user_record(user_id, start:int, size:int) -> List[Dict]:
    with Session() as s:
        try:
            stmt = select(CmRecord).where(CmRecord.user_id == user_id).order_by(CmRecord.create_time.desc()).limit(size).offset(start)
            records = s.execute(stmt).scalars().all()
            return [record.task_to_dict() for record in records]
        except Exception as e:
            print('get user record error' + str(e))
            
        

def get_record_task(record_id) -> List[Dict]:
    s = Session()
    stmt = (
        select(CmTask)
        .where(CmTask.record_id == record_id)
        .order_by(CmTask.create_time.desc())
    )
    tasks = s.execute(stmt).scalars().all()
    s.close()
    return [task.task_to_dict() for task in tasks]
       